home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / os20 / util / wbstart1_2.lha / WBStart / WBStart-Handler.c < prev    next >
C/C++ Source or Header  |  1992-09-21  |  6KB  |  232 lines

  1. /*
  2.  * WBStart-Handler.c   V1.2
  3.  *
  4.  * Handler code
  5.  *
  6.  * (c) 1991-92 Stefan Becker
  7.  *
  8.  */
  9. #include "WBStart.h"
  10. #include <clib/dos_protos.h>
  11. #include <clib/exec_protos.h>
  12. #include <clib/icon_protos.h>
  13. #include <dos/dostags.h>
  14. #include <workbench/icon.h>
  15. #include <workbench/workbench.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. /* Global data */
  20. void _waitwbmsg(void);
  21. struct Library *IconBase;
  22. static struct MsgPort *HandlerPort;
  23. static ULONG wbactive=0;            /* Number of active WB processes */
  24. static char Version[]="$VER: WBStart-Handler 1.2 (21.9.1992)";
  25.  
  26. /* Start tool as a WB process */
  27. static BOOL StartProgram(struct WBStartMsg *msg)
  28. {
  29.  char *name=msg->wbsm_Name;      /* Program name */
  30.  BPTR fl;                        /* Tool current dir */
  31.  register struct WBStartup *wbs; /* WBStartup message for tool */
  32.  struct DiskObject *tdob;        /* Tool icon */
  33.  LONG ssize;                     /* StackSize, default */
  34.  struct WBArg *wbad,*wbas;       /* Pointers to WB arguments */
  35.  char *proname=NULL;             /* Name of Project icon */
  36.  int i;
  37.  
  38.  /* Allocate memory for WBStartup */
  39.  if (!(wbs=calloc(sizeof(struct WBStartup)+
  40.                   sizeof(struct WBArg)*(msg->wbsm_NumArgs+2),1)))
  41.   return (FALSE);
  42.  
  43.  /* Go to tools current directory */
  44.  fl=CurrentDir(msg->wbsm_DirLock);
  45.  
  46.  /* Is it a project? */
  47.  if (tdob=GetDiskObject(name))
  48.   if (tdob->do_Type==WBPROJECT)
  49.    {
  50.     proname=name;                      /* Save original name */
  51.     name=strdup(tdob->do_DefaultTool); /* Get name of default tool */
  52.     FreeDiskObject(tdob);
  53.     if (!name) goto se1;               /* Enough memory? */
  54.     tdob=GetDiskObject(name);          /* Get icon of the default tool */
  55.    }
  56.  
  57.  /* Is it a tool? */
  58.  ssize=msg->wbsm_Stack;
  59.  if (tdob)
  60.   {
  61.    if (tdob->do_Type==WBTOOL)          /* Only tools supply this information */
  62.     {
  63.      if (tdob->do_ToolWindow) wbs->sm_ToolWindow=strdup(tdob->do_ToolWindow);
  64.      if (tdob->do_StackSize>ssize) ssize=tdob->do_StackSize;
  65.     }
  66.  
  67.    FreeDiskObject(tdob);
  68.   }
  69.  if (ssize<4096) ssize=4096; /* Minimum stack size is 4096 Bytes! */
  70.  ssize=(ssize+3)&(~3);       /* Stack size must be a multiple of 4! */
  71.  
  72.  /* Load tool code */
  73.  if (!(wbs->sm_Segment=LoadSeg(name))) goto se2;
  74.  
  75.  /* Build WBStartup message */
  76.  /* wbs->sm_Message.mn_Node.ln_Type=NT_MESSAGE; PutMsg() does this for us! */
  77.  wbs->sm_Message.mn_ReplyPort=HandlerPort;
  78.  wbs->sm_Message.mn_Length=sizeof(struct WBStartup);
  79.  wbs->sm_NumArgs=msg->wbsm_NumArgs+1;
  80.  wbs->sm_ArgList=wbs+1;             /* WBArg array starts after WBStartup */
  81.  
  82.  /* Initialize WBArg pointers */
  83.  wbas=msg->wbsm_ArgList;
  84.  wbad=wbs->sm_ArgList;
  85.  
  86.  /* 1. argument is the tool itself! */
  87.  if (!(wbad->wa_Lock=DupLock(msg->wbsm_DirLock))) goto se3;
  88.  if (!(wbad->wa_Name=strdup(name))) goto se4;
  89.  wbad++;
  90.  
  91.  /* If tool is a project, add it as 2. parameter to the WBArg list */
  92.  if (proname)
  93.   {
  94.    if (!(wbad->wa_Lock=DupLock(msg->wbsm_DirLock))) goto se4;
  95.    if (!(wbad->wa_Name=strdup(proname))) goto se4;
  96.    wbad++;
  97.    wbs->sm_NumArgs++;
  98.   }
  99.  
  100.  /* Copy WB arguments */
  101.  for (i=msg->wbsm_NumArgs; i; i--,wbas++,wbad++)
  102.   {
  103.    if (!(wbad->wa_Lock=DupLock(wbas->wa_Lock)))
  104.     {
  105.      wbad--;             /* Skip parameters, which don't support a lock */
  106.      wbs->sm_NumArgs--;
  107.      continue;           /* Next parameter */
  108.     }
  109.  
  110.    /* Sanity check for name string... Enforcer is watching you! */
  111.    if (!wbas->wa_Name || !(wbad->wa_Name=strdup(wbas->wa_Name))) goto se4;
  112.   }
  113.  
  114.  /* Safety first :-) */
  115.  Forbid();
  116.  
  117.  /* Create process */
  118.  if (!(wbs->sm_Process=CreateProc(wbs->sm_ArgList->wa_Name,msg->wbsm_Prio,
  119.                                 wbs->sm_Segment,ssize))) {
  120.   Permit();
  121.   goto se4;
  122.  }
  123.  
  124.  /* Set PROGDIR: *** ATTENTION: Don't try this at home, kids :-) *** */
  125.  {
  126.   struct Process *pr=wbs->sm_Process->mp_SigTask;
  127.  
  128.   pr->pr_HomeDir=DupLock(msg->wbsm_DirLock);
  129.  }
  130.  Permit();
  131.  
  132.  /* Send WBStartup message to tool */
  133.  PutMsg(wbs->sm_Process,(struct Message *) wbs);
  134.  if (proname) free(name);       /* If project, then free default tool name */
  135.  wbactive++;                    /* Tool started! */
  136.  CurrentDir(fl);
  137.  return(TRUE);
  138.  
  139.  /* An error occurred. Free all resources */
  140. se4: wbas=wbs->sm_ArgList;
  141.      for (i=wbs->sm_NumArgs; i; i--,wbas++)
  142.       {
  143.        UnLock(wbas->wa_Lock);
  144.        if (wbas->wa_Name) free(wbas->wa_Name);
  145.       }
  146. se3: UnLoadSeg(wbs->sm_Segment);
  147. se2: if (proname) free(name);
  148. se1: CurrentDir(fl);
  149.      free(wbs);
  150.      return(FALSE);
  151. }
  152.  
  153. __stkargs void _main(int arglen, char *argptr)
  154. {
  155.  ULONG gotsigs,wsig,psig;
  156.  BOOL notend=TRUE;
  157.  
  158.  /* Open icon.library */
  159.  if (!(IconBase=OpenLibrary(ICONNAME,0))) return;
  160.  
  161.  /* Create message port */
  162.  if (!(HandlerPort=CreateMsgPort()))
  163.   {
  164.    CloseLibrary(IconBase);
  165.    return;
  166.   }
  167.  
  168.  /* Make port public */
  169.  HandlerPort->mp_Node.ln_Pri=0;
  170.  HandlerPort->mp_Node.ln_Name=WBS_PORTNAME;
  171.  AddPort(HandlerPort);
  172.  
  173.  /* Init signal masks */
  174.  psig=1L<<HandlerPort->mp_SigBit;
  175.  wsig=psig|SIGBREAKF_CTRL_C;
  176.  
  177.  /* Main event loop */
  178.  while (notend)
  179.   {
  180.    /* Wait on event */
  181.    gotsigs=Wait(wsig);
  182.  
  183.    /* Got a message at our port? */
  184.    if (gotsigs&psig)
  185.     {
  186.      struct WBStartMsg *msg;
  187.  
  188.      /* Process all messages */
  189.      while (msg=GetMsg(HandlerPort))
  190.       if (msg->wbsm_Msg.mn_Node.ln_Type==NT_REPLYMSG) /* Replied message? */
  191.        {
  192.         /* This is the death message from a tool we started some time ago */
  193.         struct WBStartup *wbs=(struct WBStartup *) msg;
  194.         struct WBArg *wa=wbs->sm_ArgList;
  195.         int i=wbs->sm_NumArgs;
  196.  
  197.         while (i--)
  198.          {
  199.           UnLock(wa->wa_Lock);      /* Free WB argument */
  200.           if (wa->wa_Name) free(wa->wa_Name);
  201.           wa++;
  202.          }
  203.  
  204.         if (wbs->sm_ToolWindow)     /* Free tool window specification */
  205.          free(wbs->sm_ToolWindow);
  206.  
  207.         UnLoadSeg(wbs->sm_Segment); /* Unload code */
  208.         free(wbs);                  /* Free WBStartup */
  209.         wbactive--;                 /* One tool closed down */
  210.        }
  211.       else
  212.        {
  213.         /* We got a new message. Handle and reply it. */
  214.         msg->wbsm_Stack=StartProgram(msg);
  215.         ReplyMsg((struct Message *) msg);
  216.        }
  217.     }
  218.  
  219.    /* Received a CTRL-C? */
  220.    if ((gotsigs&SIGBREAKF_CTRL_C) && !wbactive) notend=FALSE;
  221.   }
  222.  
  223.  /* Exit handler */
  224.  RemPort(HandlerPort);
  225.  DeleteMsgPort(HandlerPort);
  226.  CloseLibrary(IconBase);
  227.  return;
  228.  
  229.  /* NOT REACHED */
  230.  _waitwbmsg();    /* Force linking of WB startup code */
  231. }
  232.